package com.gome.boot.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 字符串转其他类型工具类.
 *
 * @author baoxiufeng
 */
public class StringToUtils {
    /** 分号 */
    private static final String SEMICOLON = ";";
    /** 逗号 */
    private static final String COMMA = ",";
    /** 等号 */
    private static final String EQUAL = "=";

    /**
     * 转换字符串到指定类型值.
     *
     * @param str 待转换字符串
     * @param clazz 转换后的类型
     * @param <T> 转换后的类型泛型
     * @return 转换后的值
     */
    public static <T> T stringTo(String str, Class<T> clazz) {
        if (clazz.isAssignableFrom(String.class)) {
            return (T) str;
        }
        if (clazz.isAssignableFrom(Integer.class)) {
            try {
                return (T) Integer.valueOf(str);
            } catch (Exception e) {
                return null;
            }
        }
        if (clazz.isAssignableFrom(Long.class)) {
            try {
                return (T) Long.valueOf(str);
            } catch (Exception e) {
                return null;
            }
        }
        if (clazz.isAssignableFrom(Double.class)) {
            try {
                return (T) Double.valueOf(str);
            } catch (Exception e) {
                return null;
            }
        }
        if (clazz.isAssignableFrom(Boolean.class)) {
            try {
                return (T) Boolean.valueOf(str);
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 字符串转列表.
     * <br/>待转换字符串格式要求：key=A1,A2,A3,...An
     * <br/>分隔符顺序：逗号
     *
     * @param str 待转换字符串
     * @return 转换后的字符串列表
     */
    public static List<String> stringToList(String str) {
        return stringToList(str, String.class);
    }

    /**
     * 字符串转列表.
     * <br/>待转换字符串格式要求：key=A1,A2,A3,...An
     * <br/>分隔符顺序：逗号
     *
     * @param str 待转换字符串
     * @param clazz 转换后的值类型
     * @param <T> 转换后的值类型泛型
     * @return 转换后的字符串列表
     */
    public static <T> List<T> stringToList(String str, Class<T> clazz) {
        return stringToList(str, clazz, COMMA);
    }

    /**
     * 字符串转列表.
     * <br/>待转换字符串格式要求：key=A1,A2,A3,...An
     * <br/>分隔符顺序：逗号
     *
     * @param str 待转换字符串
     * @param splitChar 转换用字符
     * @return 转换后的字符串列表
     */
    public static List<String> stringToList(String str, String splitChar) {
        return stringToList(str, String.class, splitChar);
    }

    /**
     * 字符串转列表.
     * <br/>待转换字符串格式要求：key=A1,A2,A3,...An
     * <br/>分隔符顺序：逗号
     *
     * @param str 待转换字符串
     * @param clazz 转换后的值类型
     * @param splitStr 分隔符
     * @param <T> 转换后的值类型泛型
     * @return 转换后的字符串列表
     */
    public static <T> List<T> stringToList(String str, Class<T> clazz, String splitStr) {
        if (CommonUtils.isEmpty(str)) {
            return new ArrayList<T>(0);
        }
        String[] vs = str.split(splitStr == null ? COMMA : splitStr);
        List<T> list = new ArrayList<T>(vs.length);
        T value = null;
        for (String v : vs) {
            value = stringTo(v.trim(), clazz);
            if (value != null) {
                list.add(value);
            }
        }
        return list;
    }

    /**
     * 字符串转集合.
     * <br/>待转换字符串格式要求：key=A1=A1,B1=B1,C1=C1
     * <br/>分隔符顺序：逗号 -> 等号
     *
     * @param str 待转换字符串
     * @return 转换后的集合
     */
    public static Map<String, String> stringToMap(String str) {
        return stringToMap(str, String.class);
    }

    /**
     * 字符串转集合.
     * <br/>待转换字符串格式要求：key=A1=A1,B1=B1,C1=C1
     * <br/>分隔符顺序：逗号 -> 等号
     *
     * @param str 待转换字符串
     * @param clazz 转换后的值类型
     * @param <T> 转换后的值类型泛型
     * @return 转换后的集合
     */
    public static <T> Map<String, T> stringToMap(String str, Class<T> clazz) {
        if (CommonUtils.isEmpty(str)) {
            return new HashMap<String, T>(0);
        }
        String[] vs = str.split(COMMA);
        Map<String, T> map = new HashMap<String, T>(vs.length);
        for (String v : vs) {
            String[] kv = v.trim().split(EQUAL);
            if (kv.length == 2) {
                map.put(kv[0].trim(), stringTo(kv[1], clazz));
            }
        }
        return map;
    }

    /**
     * 字符串转列表集合.
     * <br/>待转换字符串格式要求：key=A=A1,A2,A3,...An;B=B1,B2,B3,...Bn
     * <br/>分隔符顺序：分号 -> 等号 -> 逗号
     *
     * @param str 待转换字符串
     * @return 转换后的列表集合
     */
    public static Map<String, List<String>> stringToListMap(String str) {
        return stringToListMap(str, String.class);
    }

    /**
     * 字符串转列表集合.
     * <br/>待转换字符串格式要求：key=A=A1,A2,A3,...An;B=B1,B2,B3,...Bn
     * <br/>分隔符顺序：分号 -> 等号 -> 逗号
     *
     * @param str 待转换字符串
     * @param clazz 转换后的列表中值类型
     * @param <T> 转换后的值类型泛型
     * @return 转换后的列表集合
     */
    public static <T> Map<String, List<T>> stringToListMap(String str, Class<T> clazz) {
        if (CommonUtils.isEmpty(str)) {
            return new HashMap<String, List<T>>(0);
        }
        String[] vs = str.split(SEMICOLON);
        Map<String, List<T>> map = new HashMap<String, List<T>>(vs.length);
        for (String v : vs) {
            String[] kv = v.trim().split(EQUAL);
            if (kv.length == 2) {
                map.put(kv[0], stringToList(kv[1], clazz));
            }
        }
        return map;
    }

    /**
     * 使用逗号分隔给定字符串.
     *
     * @param str 待分隔字符串
     * @return 分隔后的字符串数组
     */
    public static String[] stringToArray(String str) {
        return stringToArray(str, String.class);
    }

    /**
     * 使用逗号分隔给定字符串.
     *
     * @param str 待分隔字符串
     * @param splitStr 分隔符
     * @return 分隔后的字符串数组
     */
    public static String[] stringToArray(String str, String splitStr) {
        return stringToArray(str, String.class);
    }

    /**
     * 使用逗号分隔给定字符串.
     *
     * @param str 待分隔字符串
     * @param clazz 转换后的值类型
     * @param <T> 转换后的值类型泛型
     * @return 分隔后的字符串数组
     */
    public static <T> T[] stringToArray(String str, Class<T> clazz) {
        if (CommonUtils.isEmpty(str)) {
            return null;
        }
        String[] vs = str.split(COMMA);
        List<T> list = new ArrayList<T>(vs.length);
        T value = null;
        for (String v : vs) {
            value = stringTo(v.trim(), clazz);
            if (value != null) {
                list.add(value);
            }
        }
        return (T[]) list.toArray();
    }

    /**
     * 根据分隔符拆分字符串为指定类型的值数组.
     * <br/>例如：127.0.0.1:9300 => ["127.0.0.1", 9300]
     *
     * @param str 待转换字符串
     * @param splitStr 分隔符
     * @param clazz 转换后的值类型
     * @return 转换后的值数组
     */
    public static Object[] stringToArray(String str, String splitStr, Class... clazz) {
        if (CommonUtils.isAnyBlank(str, splitStr) || CommonUtils.isEmpty(clazz)) {
            return new Object[0];
        }
        String[] vs = str.split(splitStr);
        int validLen = Math.min(vs.length, clazz.length);
        Object[] array = new Object[validLen];
        for (int i = 0; i < validLen; i++) {
            array[i] = stringTo(vs[i].trim(), clazz[i]);
        }
        return array;
    }
}
